package edu.vt.ece_3574.amber_alert;

import java.util.ArrayList;

import com.google.android.maps.GeoPoint;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.IBinder;
import android.util.Log;
import edu.vt.ece_3574.amber_alert.AlertSettings.Battery;
import edu.vt.ece_3574.amber_alert.AlertSettings.PollingInterval;
import edu.vt.ece_3574.amber_alert.accounts.Account;
import edu.vt.ece_3574.amber_alert.database.DatabaseHandler;
import edu.vt.ece_3574.amber_alert.location.LocationManagerHandler;
import edu.vt.ece_3574.amber_alert.location.SendCurrentLocationReceiver;
import edu.vt.ece_3574.amber_alert.messaging.MessagingUtils;

/**
 * This class is a continuously running background service used to accomplish various tasks that should
 * run in the background if the application is closed
 */

public class BackgroundService extends Service{

	private static final String TAG = BackgroundService.class.getSimpleName();
	private Updater updater;
	public static boolean serviceStarted = false;
	private static ArrayList<Account> account = new ArrayList<Account>();
	private static Account currentAccount;
	private final SendCurrentLocationReceiver smsReceiver = new SendCurrentLocationReceiver();
	private final BroadcastReceiver batteryReceiver = Battery.get();
	private String batteryMessage = "Alert: Battery power below specified level!";
	private String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
	private String BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
	LocationManager locationManager;
	GeoPoint location;

	@Override
	public void onCreate() {
		super.onCreate();
		updater = new Updater();
		Log.d(TAG, "onCreated");
		final IntentFilter smsIntent = new IntentFilter();
		final IntentFilter batteryIntent = new IntentFilter();
		smsIntent.addAction(SMS_RECEIVED);
		batteryIntent.addAction(BATTERY_CHANGED);
		locationManager = LocationManagerHandler.getLocationManager();
		this.registerReceiver(this.smsReceiver, smsIntent);
		this.registerReceiver(this.batteryReceiver, batteryIntent);
	}

	@Override
	public void onStart(Intent intent, int startId) {	
		updater.start();
		Log.d(TAG, "onStarted");
		//super.onStart(intent, startId);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		updater.stop();
		this.unregisterReceiver(smsReceiver);
		this.unregisterReceiver(batteryReceiver);
		serviceStarted = false;
		Log.d(TAG, "onDestroyed");
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}


	/**This Class is used to send location info to primaries every DELAY miliseconds
	 * The time can be changed by altering DELAY which counts in milliseconds
	 * The method run() is called by start()
	 */
	class Updater extends Thread {
		static final long DELAY = 30000;

		@Override
		public void run() {
			while(AmberAlertApplication.get().getCurrentAccount().getType().equals("Member")){				
				try {
					Log.d(TAG, "Background Service Running");
					if(account.size() == 0) {
						Log.d(TAG, "if accounts list is emtpy, get from accountsList");
						account = AmberAlertApplication.get().getCurrentAccount().getAssociatedAccounts();
						currentAccount = AmberAlertApplication.get().getCurrentAccount();
					}
					else {
						Log.d(TAG, "one or more primaries present");
						location = getLocation();
						currentAccount.setLocation(location);
						for(Account accounts : account) {
							Log.d(TAG, "notify primaries of new location");
							DatabaseHandler.get().notifyAccountThisLocationIsUpdated(accounts.getName());
						}						
						if(Battery.BatisOn()) {
							Log.d(TAG, "Battery checking is turned on");
							if(!Battery.BatLevel()) {						
								Log.d(TAG,"Battery Level is Below Specification");
								for(Account accounts : account) {
									Log.d(TAG, "sending text messages for battery");
									int batteryLevel = Battery.getSetLevel();
									batteryMessage = "Alert: Battery power is below " + String.valueOf(batteryLevel) + "%!";
									MessagingUtils.get().sendSMS(accounts.getNumber(), batteryMessage);
								}
							}
						}
					}
					Log.d(TAG, "Current Interval: "+Integer.toString(PollingInterval.getPollInterval()));
					Thread.sleep(PollingInterval.getPollInterval());
				} 
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public GeoPoint getLocation() {
		GeoPoint locationPoint;
		Log.d(TAG, "entered getLocation method");
		Location lastLocation = locationManager.getLastKnownLocation("gps");
		if(lastLocation == null) {
			Log.d(TAG, "gps returning null locations");
			locationPoint = new GeoPoint(0,0);
		}
		else {
			Log.d(TAG, "if location string is not null");
			locationPoint = new GeoPoint((int)(lastLocation.getLatitude() * 1e6), (int)(lastLocation.getLongitude() * 1e6));
		}
		return locationPoint;
	}
}
